package ar.edu.itba.it.pdc;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import javax.mail.internet.MimeUtility;

import com.google.common.io.LineReader;

import ar.edu.itba.it.pdc.commons.Header;
import ar.edu.itba.it.pdc.commons.Mail;
import ar.edu.itba.it.pdc.commons.POP3Utils;

public class L33tFilter {

	public static String CRLF = "\r\n";

	public static void main(String[] args) {
		Mail m = new Mail(System.in);
		filter(m, System.out);
	}

	public static void filter(Mail m, OutputStream out) {
		if (m.getContentType().contains("multipart")) {
			printHeaders(m, System.out);
			for (Mail p : m.getParts()) {
				filter(p, System.out);
			}
		} else {
			_filter(m, System.out);
		}
	}

	private static void printHeaders(Mail m, OutputStream stdout) {
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(stdout));

		try {
			for (Header h : m.getHeaders()) {
				out.write(POP3Utils.fold(0, h.getHeader()));
				out.write(CRLF);
			}
			out.write(CRLF);
			out.flush();
		} catch (Exception e) {

		}
	}

	private static void _filter(Mail m, OutputStream stdout) {
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(stdout));

		try {
			// Saltea headers
			printHeaders(m, stdout);

			String a;
			char c;

			if (m.getContentType().contains("text")) {
				StringBuffer b = new StringBuffer();
				LineReader bod = m.getBody();
				while ((a = decode(m, bod.readLine())) != null) {
					b.delete(0, b.length());
					for (int i = 0; i < a.length(); i++) {
						switch (Character.toLowerCase((c = a.charAt(i)))) {
						case 'a':
							b.append('4');
							break;
						case 'e':
							b.append('3');
							break;
						case 'i':
							b.append('1');
							break;
						case 'o':
							b.append('0');
							break;
						default:
							b.append(c);
						}
					}
					out.write(encode(m, b.toString()));
					out.write(CRLF);
				}
			} else {
				LineReader lrb = m.getBody();
				while ((a = lrb.readLine()) != null) {
					out.write(a);
					out.write(CRLF);
				}
				out.write(CRLF);
			}
			out.flush();

		} catch (IOException e) {
		}
	}

	private static String decode(Mail m, String s) {
		if (s == null) {
			return null;
		} else if (s.isEmpty()) {
			return "";
		} else {
			try {
				BufferedReader resp = new BufferedReader(new InputStreamReader(
						MimeUtility.decode(
								new ByteArrayInputStream(s.getBytes()), m
										.getContentTransferEncoding()
										.getValue())));
				String r = resp.readLine();
				return r;
			} catch (Exception e) {
			}
			return s;
		}
	}

	private static String encode(Mail m, String s) {
		if (s == null) {
			return null;
		} else if (s.isEmpty()) {
			return "";
		} else {
			try {
				ByteArrayOutputStream out = new ByteArrayOutputStream();
				OutputStream encoder = MimeUtility.encode(out, m.getContentTransferEncoding().getValue());

				encoder.write(s.getBytes(), 0, s.length());
				encoder.flush();

				return new String(out.toByteArray());

			} catch (Exception e) {
			}
		}
		return s;
	}
}